/*
 *  BirthClinicConfigurationLoader.cpp
 *  roborobo-online
 *
 *  Created by Antonio Gonzalez on 29/04/10.
 *
 */

#include "Config/BirthClinicConfigurationLoader.h"

#include "BirthClinic/include/BirthClinic.h"
#include "BirthClinic/include/BCAgentWorldModel.h"
#include "BirthClinic/include/BCAgentObserver.h"
#include "BirthClinic/include/BCControlArchitecture.h"
#include "BirthClinic/include/BCSharedData.h"

#include "World/RobotAgentWorldInterface.h"

BirthClinicConfigurationLoader::BirthClinicConfigurationLoader() {
	// create the single instance of Agent-World Interface.
	_AgentWorldInterface = new RobotAgentWorldInterface();
	readProperties();
}

BirthClinicConfigurationLoader::~BirthClinicConfigurationLoader() {
	//nothing to do
}

WorldObserver* BirthClinicConfigurationLoader::make_WorldObserver(World* wm) {
	return new BirthClinic(wm);
}

RobotAgentWorldModel* BirthClinicConfigurationLoader::make_RobotAgentWorldModel() {
	return new BCAgentWorldModel();
}

AgentObserver* BirthClinicConfigurationLoader::make_AgentObserver(
		RobotAgentWorldModel* wm) {
	return new BCAgentObserver(wm);
}

BehaviorControlArchitecture* BirthClinicConfigurationLoader::make_BehaviorControlArchitecture(
		RobotAgentWorldModel* wm) {
	return new BCControlArchitecture(wm);
}

RobotAgentWorldInterface* BirthClinicConfigurationLoader::make_RobotAgentWorldInterface() {
	return _AgentWorldInterface;
}
bool BirthClinicConfigurationLoader::readProperties() {
	bool returnValue = true;

	std::cout << "Reading properties..." << std::endl;

	if (gProperties.hasProperty("gNbOfOrganism")) {
		convertFromString<int>(BCSharedData::_gNbOfOrganism,
				gProperties.getProperty("gNbOfOrganism"), std::dec);
	} else {
		std::cerr << "[MISSING] gNbOfOrganism value is missing." << std::endl;
	}

	if (gProperties.hasProperty("genotypeMaxLength")) {
		convertFromString<int>(BCSharedData::_genotypeMaxLength,
				gProperties.getProperty("genotypeMaxLength"), std::dec);
	} else {
		std::cerr << "[MISSING] genotypeMaxLength value is missing."
				<< std::endl;
		returnValue = false;
	}

	if (gProperties.hasProperty("genotypeMinLength")) {
		convertFromString<int>(BCSharedData::_genotypeMinLength,
				gProperties.getProperty("genotypeMinLength"), std::dec);
	} else {
		std::cerr << "[MISSING] genotypeMinLength value is missing."
				<< std::endl;
		returnValue = false;
	}

	if (gProperties.hasProperty("birthClinicWidth")) {
		convertFromString<int>(BCSharedData::_birthClinicWidth,
				gProperties.getProperty("birthClinicWidth"), std::dec);
	} else {
		std::cerr << "[MISSING] birthClinicWidth value is missing."
				<< std::endl;
		returnValue = false;
	}

	if (gProperties.hasProperty("birthClinicHeight")) {
		convertFromString<int>(BCSharedData::_birthClinicHeight,
				gProperties.getProperty("birthClinicHeight"), std::dec);
	} else {
		std::cerr << "[MISSING] birthClinicHeight value is missing."
				<< std::endl;
		returnValue = false;
	}

	if (gProperties.hasProperty("birthClinicCenterPosX")) {
		convertFromString<int>(BCSharedData::_birthClinicCenterPosX,
				gProperties.getProperty("birthClinicCenterPosX"), std::dec);
	} else {
		std::cerr << "[MISSING] birthClinicCenterPosX value is missing."
				<< std::endl;
		returnValue = false;
	}

	if (gProperties.hasProperty("birthClinicCenterPosY")) {
		convertFromString<int>(BCSharedData::_birthClinicCenterPosY,
				gProperties.getProperty("birthClinicCenterPosY"), std::dec);
	} else {
		std::cerr << "[MISSING] birthClinicCenterPosY value is missing."
				<< std::endl;
		returnValue = false;
	}

	if (gProperties.hasProperty("organismMaxLife")) {
		convertFromString<int>(BCSharedData::_organismMaxLife,
				gProperties.getProperty("organismMaxLife"), std::dec);
	} else {
		std::cerr << "[MISSING] organismMaxLife value is missing." << std::endl;
	}

	if (gProperties.hasProperty("organismMinLife")) {
		convertFromString<int>(BCSharedData::_organismMinLife,
				gProperties.getProperty("organismMinLife"), std::dec);
	} else {
		std::cerr << "[MISSING] organismMinLife value is missing." << std::endl;
	}

	if (gProperties.hasProperty("infancyDuration")) {
		convertFromString<int>(BCSharedData::_organismInfancyDuration,
				gProperties.getProperty("infancyDuration"), std::dec);
	} else {
		std::cerr << "[MISSING] infancyDurantion value is missing."
				<< std::endl;
	}

	if (gProperties.hasProperty("matingViewRange")) {
		convertFromString<int>(BCSharedData::_matingViewRange,
				gProperties.getProperty("matingViewRange"), std::dec);
	} else {
		std::cerr << "[MISSIG] matingViewRange value is missing."
				<< std::endl;
	}

	if (gProperties.hasProperty("mutationProbability")) {
		convertFromString<int>(BCSharedData::_mutationProbability,
				gProperties.getProperty("mutationProbability"), std::dec);
	} else {
		std::cerr << "[MISSING] mutationProbability value is missing."
				<< std::endl;
		returnValue = false;
	}

	if (gProperties.hasProperty("postnatalPeriod")){
		convertFromString<int>(BCSharedData::_postnatalPeriod,
				gProperties.getProperty("postnatalPeriod"),std::dec);
	} else {
		std::cerr << "[MISSING] postnatalPeriod value is missing." << std::endl;
	}

	if (gProperties.hasProperty("constructionPeriod")){
		convertFromString<int>(BCSharedData::_constructionPeriod,
				gProperties.getProperty("constructionPeriod"),std::dec);
	} else {
		std::cerr << "[MISSING] gestationPeriod value is missing." << std::endl;
	}

	if (gProperties.hasProperty("registerStatisticsInterval")){
		convertFromString<int>(BCSharedData::_statisticsInterval,
				gProperties.getProperty("registerStatisticsInterval"),std::dec);
	} else {
		std::cerr << "[MISSING] registerStatisticsInterval value is missing." << std::endl;
	}

	gProperties.checkAndGetPropertyValue("gMainAgentMaskImageFilename",
			&BCSharedData::_gMainAgentMaskImageFilename, true);
	gProperties.checkAndGetPropertyValue("gComponentAgentMaskImageFilename",
			&BCSharedData::_gComponentAgentMaskImageFilename, true);

	gProperties.checkAndGetPropertyValue("birthClinicLogLife", &BCSharedData::_birthClinicLogFilename, true);
		BCSharedData::_birthClinicLogFile.open(BCSharedData::_birthClinicLogFilename.c_str());
		if (!BCSharedData::_birthClinicLogFile) {
			std::cout << "[error] Cannot open log file " << BCSharedData::_birthClinicLogFilename << "." << std::endl << std::endl;
		}

	BCSharedData::_robotId = 0;

	return returnValue;
}
